<?php
namespace EasySwoole\EasySwoole;


use EasySwoole\EasySwoole\Swoole\EventRegister;
use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\Http\Request;
use EasySwoole\Http\Response;
use App\WebSocket\WebSocketParser;
use EasySwoole\Socket\Dispatcher;
use FFMpeg\FFMpeg;
use FFMpeg\FFProbe;

class EasySwooleEvent implements Event
{

    public static function initialize()
    {
        // TODO: Implement initialize() method.
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        /**
         * **************** websocket控制器 **********************
         */
        // 创建一个 Dispatcher 配置
        $conf = new \EasySwoole\Socket\Config();
        // 设置 Dispatcher 为 WebSocket 模式
        $conf->setType(\EasySwoole\Socket\Config::WEB_SOCKET);
        // 设置解析器对象
        $conf->setParser(new WebSocketParser());
        // 创建 Dispatcher 对象 并注入 config 对象
        $dispatch = new Dispatcher($conf);
        // 给server 注册相关事件 在 WebSocket 模式下  on message 事件必须注册 并且交给 Dispatcher 对象处理
        $register->set(EventRegister::onMessage, function (\Swoole\Websocket\Server $server, \Swoole\Websocket\Frame $frame) use ($dispatch) {
            $dispatch->dispatch($server, $frame->data, $frame);
        });
        $server = ServerManager::getInstance()->getSwooleServer();
        $server->on('handshake', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
            // print_r( $request->header );
            // if (如果不满足我某些自定义的需求条件，那么返回end输出，返回false，握手失败) {
            //    $response->end();
            //     return false;
            // }

            // websocket握手连接算法验证
            $secWebSocketKey = $request->header['sec-websocket-key'];
            $patten          = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
            if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
                $response->end();
                return false;
            }
//            echo $request->header['sec-websocket-key'];
            $key = base64_encode(sha1(
                $request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
                true
            ));

            $headers = [
                'Upgrade'               => 'websocket',
                'Connection'            => 'Upgrade',
                'Sec-WebSocket-Accept'  => $key,
                'Sec-WebSocket-Version' => '13',
            ];

            // WebSocket connection to 'ws://127.0.0.1:9502/'
            // failed: Error during WebSocket handshake:
            // Response must not include 'Sec-WebSocket-Protocol' header if not present in request: websocket
            if (isset($request->header['sec-websocket-protocol'])) {
                $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol'];
            }

            foreach ($headers as $key => $val) {
                $response->header($key, $val);
            }

            $response->status(101);
            $response->end();
        });
//        ################# tcp 服务器1 没有处理粘包 #####################
        $tcp1ventRegister = $subPort1 = ServerManager::getInstance()->addServer('tcp1', 9506, SWOOLE_TCP, '0.0.0.0', [
            // 'open_length_check' => false,//不验证数据包
            'open_http_protocol' => false,
            'open_websocket_protocol' => false,
            'buffer_output_size' => 32 * 1024 *1024,
            //'open_eof_check' => true,
            //'package_eof' => "\r\n\r\n",
            'package_max_length' => 1024 * 1024 * 2,
        ]);

        $tcp1ventRegister->set(EventRegister::onReceive,function (\Swoole\Server $server, int $fd, int $reactor_id, string $data) {
            //$client = $server->getClientInfo($fd);
            //echo 'Stream Connected:'.$client['remote_ip'].':'.$client['remote_port'] .PHP_EOL ;
            $server = ServerManager::getInstance()->getSwooleServer();
            if($server instanceof \Swoole\WebSocket\Server){
                foreach ($server->connections as $connection){
                    if($connection != $fd){
                        $server->push($connection, $data, WEBSOCKET_OPCODE_BINARY);
                    }
                }
            }
        });
    }

    public static function onRequest(Request $request, Response $response): bool
    {
        // TODO: Implement onRequest() method.
        return true;
    }

    public static function afterRequest(Request $request, Response $response): void
    {
        // TODO: Implement afterAction() method.
    }
}